*** yacc.y	Mon Oct 11 14:59:56 1993
--- yacc.y.frac	Mon Oct 11 14:46:03 1993
***************
*** 43,49 ****
  #include "libobj/sphere.h"
  #include "libobj/torus.h"
  #include "libobj/triangle.h"
! 
  #include "liblight/point.h"
  #include "liblight/infinite.h"
  #include "liblight/spot.h"
--- 43,52 ----
  #include "libobj/sphere.h"
  #include "libobj/torus.h"
  #include "libobj/triangle.h"
! #include "libobj/ifs.h"
! #include "libobj/mountain.h"
! #include "libobj/fractalobject.h"
! #include "libobj/allocmatrix.h"
  #include "liblight/point.h"
  #include "liblight/infinite.h"
  #include "liblight/spot.h"
***************
*** 86,100 ****
--- 89,114 ----
  Atmosphere *CurEffect = (Atmosphere *)NULL;	/* Current atmos. effects */ 
  PointList *Polypoints;				/* List of vertices */
  MetaList *Metapoints, *Metapoint;
+ PointPool *Pointpool;
+ TrianglePool *Trianglepool;
+ EntityPool *Entitypool;
+ FractalEntity *CurrEntity;
+ FractalTriangle *CurrTriangle;
+ FractalPoint *CurrPoint;
+ int    count;
  extern FILE *yyin;				/* input file pointer */
  extern int yylineno;				/* Current line # in file */
  extern Atmosphere *AtmosEffects;		/* atmospheric effects */
  extern Medium TopMedium;			/* "air" */
+ static IfsOptions ifsOptions;                   /* options for IFS object */
+ static int ifsTransformRang;                    /* rang of IFS map */
  extern void	GeomAddToDefined(),
  		LightAddToDefined(),
  		SurfaceAddToDefined();
  extern Surface	*SurfaceGetNamed();
  extern Geom 	*GeomGetNamed();
+ int itemp;
+ 
  %}
  %union {
  	char *c;
***************
*** 112,117 ****
--- 126,139 ----
  	Trans *trans;
  	Expr *e;
  	SymtabEntry *sym;
+ 	IfsTransList *translist;
+         HeightValue   *heightvalues;
+         StartGridStruct *startgrid;
+         FractalClosure *fractalclosure;
+         PointPool *Fpointpool;
+         TrianglePool *Ftrianglepool;
+         EntityPool *Fentitypool;
+         TriangleList *Fentitytriangles;
  }
  %token <d> tFLOAT
  %token <c> tSTRING tFILENAME
***************
*** 132,137 ****
--- 154,164 ----
  %token tIMAGE tSMOOTH tCOMPONENT tTEXTSURF tRANGE tTILE tSTARTTIME tFRAMELENGTH
  %token tNAME tFILTER tGAUSS tBODY tSAMPLE tEXTINCT tWINDY tMOUNT
  %token tSHUTTER tFRAMES
+ %token tIFS tMINSIZE tMAXDEPTH tBOUNDING
+ %token tNORMALWEIGHTING tLOWPASS tHIGHPASS tCONSTANT 
+ %type <i> IfsNormalWeightingMethod
+ %token tMOUNTAIN
+ %token tFRACTALOBJECT tFPOINTS tFTRIANGLES tFENTITIES tENTITY
  %type <c> Filename
  %type <e> AnimExpr MExpr ParenExpr
  %type <d> Expr Float
***************
*** 152,158 ****
--- 179,197 ----
  %type <map> Mapping MapMethod OptMapping
  %type <trans> TransformType
  %type <sym> Symtabent
+ %type <obj> IfsCondensation IfsLeaves Ifs CIfs
+ %type <translist> IfsTransforms
+ %type <obj> Mountain
+ %type <obj> FractalObject
+ %type <heightvalues> HeightValues
+ %type <startgrid> StartGrid
+ %type <Fpointpool> FPointPool
+ %type <Ftrianglepool> FTrianglePool
+ %type <Fentitypool> FEntityPool
+ %type <Fentitytriangles> FEntityTriangles
+ %type <fractalclosure> FFractalClosure
  
+ 
  %left '+' '-'
  %left '*' '/' '%'
  %left UMINUS
***************
*** 257,262 ****
--- 296,305 ----
  		| Disc
  		| Torus
  		| Blob
+ 		| Ifs
+ 		| CIfs
+                 | Mountain
+                 | FractalObject
  		;
  NameObject	: tNAME tSTRING TransTextObj
  		{
***************
*** 968,973 ****
--- 1011,1181 ----
  			$$ = GeomHfCreate($2);
  		}
  		;
+ Mountain        : tMOUNTAIN OptSurface Vec2d Vec2d Float Float Float Float Float StartGrid
+ 
+                 {
+                         $$ = GeomMountainCreate($3, $4, (int)$5, $6, (int)$7, (int)$8, $9, $10);
+                         if ($$)
+                             $$->surf = $2;
+                 }
+                 | tMOUNTAIN Vec2d Vec2d Float Float Float Float Float StartGrid
+                 {
+                         $$ = GeomMountainCreate($2, $3, (int)$4, $5, (int)$6, (int)$7, $8, $9);
+                 }
+                 ;
+ HeightValues    : HeightValues Float
+                 {
+                        $$ = (HeightValue *)Malloc(sizeof(HeightValue));
+                        $$->Next  = $1;
+                        $$->Value = $2;
+                 }
+                 | Float
+                 {
+                       $$ = (HeightValue *)Malloc(sizeof(HeightValue));
+                       $$->Value = $1;
+                       $$->Next  = NULL;
+                 }
+                 ;
+ StartGrid       : HeightValues
+                 {
+                        int    i,j,k;
+                        HeightValue  *CurrHV, *CurrHV2;
+                        for (i = 0, CurrHV = $1; CurrHV != NULL; CurrHV = CurrHV->Next, i++);
+                        for (j = 1; j*j < i; j++);
+                        if (j*j != i) RLerror(RL_ABORT, "Invalid number of startgridvalues: %d\n", i);
+                        else {
+                            $$ = (StartGridStruct *)share_malloc(sizeof(StartGridStruct));
+                            if ($$) {
+                                $$->Size = j-1;
+                                CurrHV = $1;
+                                $$->Data = AllocMatrix(Float, j, j);
+                                for (i = 0; i < j; i++)
+                                   for (k = 0; k < j; k++) {
+                                         $$->Data[i][k] = CurrHV->Value;
+                                         CurrHV2 = CurrHV;
+                                         CurrHV = CurrHV->Next;
+                                         free(CurrHV2);
+                                   }
+                            }
+                        }
+                 }
+                 ;
+ 
+ FractalObject:  tFRACTALOBJECT OptSurface Float Float Float Float FFractalClosure
+                 {
+                    $$ = GeomFractalObjCreate((int)$3, $4, $5, $6, $7);
+                    if ($$)
+                        $$->surf = $2;
+                 }
+                 ;
+ FFractalClosure: FPointPool FTrianglePool FEntityPool
+                 {
+                     $$ = (FractalClosure *)share_malloc(sizeof(FractalClosure));
+                     $$->Pointpool = $1;
+                     $$->Trianglepool = $2;
+                     $$->Entitypool = $3;
+                 }
+                 ;
+ FPointPool:  tFPOINTS 
+              {
+                 Pointpool = (PointPool *)share_malloc(sizeof(PointPool));
+                 Pointpool->Points = (FractalPoint *)share_malloc(PointsToAllocate * sizeof(FractalPoint));
+                 Pointpool->NumberOfPoints = 0;
+                 Pointpool->PointsAllocated = PointsToAllocate;
+              }
+              FPoints
+              {
+                 $$ = Pointpool;
+              }
+              ;
+ FPoints:   FPoint
+            {
+            }
+            | FPoint FPoints
+            {
+            }
+            ;
+ FPoint:  Float Float Float
+          {
+              CheckPoints(Pointpool->Points, Pointpool->NumberOfPoints, Pointpool->PointsAllocated);
+              CurrPoint = &Pointpool->Points[Pointpool->NumberOfPoints++];
+              CurrPoint->x = $1;
+              CurrPoint->y = $2;
+              CurrPoint->z = $3;
+          }
+          ;
+ FTrianglePool:  tFTRIANGLES
+              {
+                 Trianglepool = (TrianglePool *)share_malloc(sizeof(TrianglePool));
+                 Trianglepool->Triangles = (FractalTriangle *)share_malloc(TrianglesToAllocate * sizeof(FractalTriangle));
+                 Trianglepool->NumberOfTriangles = 0;
+                 Trianglepool->TrianglesAllocated = TrianglesToAllocate;
+              }
+              FTriangles
+              {
+                 $$ = Trianglepool;
+              }
+              ;
+ FTriangles: FTriangle
+             {
+             }
+             | FTriangle FTriangles
+             {
+             }
+             ;
+ FTriangle:  Float Float Float
+             {
+                 CheckTriangles(Trianglepool->Triangles, Trianglepool->NumberOfTriangles,
+                                Trianglepool->TrianglesAllocated);
+                 CurrTriangle = &Trianglepool->Triangles[Trianglepool->NumberOfTriangles++];
+                 CurrTriangle->Point[0] = $1 - 1;
+                 CurrTriangle->Point[1] = $2 - 1;
+                 CurrTriangle->Point[2] = $3 - 1;
+             }
+             ;
+ FEntityPool:  tFENTITIES
+              {
+                 Entitypool = (EntityPool *)share_malloc(sizeof(EntityPool));
+                 Entitypool->Entities = (FractalEntity *)share_malloc(EntitiesToAllocate * sizeof(FractalEntity));
+                 Entitypool->NumberOfEntities = 0;
+                 Entitypool->EntitiesAllocated = EntitiesToAllocate;
+              } 
+              FEntities
+              {
+                 $$ = Entitypool;
+              } 
+              ;
+ FEntities: FEntity
+            {
+            }
+            | FEntity FEntities
+            {
+            }
+            ;
+ FEntity:  tENTITY Float Float Float FEntityTriangles
+           {
+               CheckEntities(Entitypool->Entities, Entitypool->NumberOfEntities,
+                                Entitypool->EntitiesAllocated);
+               CurrEntity = &Entitypool->Entities[Entitypool->NumberOfEntities++];
+               CurrEntity->XSize = $2;
+               CurrEntity->YSize = $3;
+               CurrEntity->ZSize = $4;
+               CurrEntity->Triangles = $5;
+           }
+           ;
+ FEntityTriangles: Float
+                   {
+                       $$ = (TriangleList *)share_malloc(sizeof(TriangleList));
+                       $$->TriangleNumber = $1 - 1;
+                       $$->Next = NULL;
+                   }
+                   | FEntityTriangles Float
+                   {
+                       $$ = (TriangleList *)share_malloc(sizeof(TriangleList));
+                       $$->TriangleNumber = $2 - 1;
+                       $$->Next = $1;
+                   }
+                   ;
  Poly		: tPOLY OptSurface Polypoints
  		{
  			$$ = GeomPolygonCreate(Polypoints, Npoints,
***************
*** 1186,1191 ****
--- 1394,1511 ----
  			Metapoint->next = Metapoints;
  			Metapoints = Metapoint;
  			Npoints++;
+ 		}
+ 		;
+ Ifs		: IfsKey OptSurface IfsTransforms IfsOptions tEND
+ 		{
+ 			$$ = GeomIfsCreate($3, &ifsOptions);
+ 			if ($$) 
+ 				$$->surf = $2;
+ 		}
+ 		;
+ CIfs		: IfsKey OptSurface IfsCondensation IfsLeaves IfsTransforms IfsOptions tEND
+ 		{
+ 			$$ = GeomCIfsCreate($5, $3, $4, &ifsOptions);
+ 			if ($$) 
+ 				$$->surf = $2;
+ 		}
+ 		;
+ IfsKey          : tIFS  /* set option defaults */
+                 {
+                         ifsTransformRang = 1;
+                         ifsOptions.depth = 99999999;
+                         ifsOptions.size = 0.;
+                         ifsOptions.normalweighting = HIGHPASS_NORMAL_WEIGHTING;
+ 			ifsOptions.boxbounding = ifsOptions.spherebounding = FALSE;
+ 			ifsOptions.listfilename = NULL;
+                 }
+                 ;
+ IfsCondensation	: TransTextObj ','
+ 		{
+ 			$$ = $1;
+ 		}
+ 		;
+ IfsLeaves       : TransTextObj ',' /* Oppenheimer trees */
+                 {
+                         $$ = $1;
+                 }
+                 | /* no leaves -> a true IFS */
+                 {
+                         $$ = (Geom *)NULL;
+                 }
+                 ;
+ IfsTransforms	: OptIfsTransformRang IfsTransform
+ 		{
+ 			$$ = (IfsTransList *)Malloc(sizeof(IfsTransList));
+ 			$$->trans = TransHead;
+ 			$$->transtail = TransTail;
+ 			$$->next = (IfsTransList *)NULL;
+                         $$->rang = ifsTransformRang;
+ 		}
+ 		| IfsTransforms ',' OptIfsTransformRang IfsTransform
+ 		{
+ 			$$ = (IfsTransList *)Malloc(sizeof(IfsTransList));
+ 			$$->trans = TransHead;
+ 			$$->transtail = TransTail;
+ 			$$->next = $1;
+                         $$->rang = ifsTransformRang;
+ 		}
+ 		;
+ IfsTransform	: TransformType
+ 		{
+ 			TransHead = TransTail = $1;
+ 		}
+ 		| IfsTransform PostTransform
+ 		;
+ OptIfsTransformRang : IExpr
+                 {
+                         ifsTransformRang = $1;
+                 }
+                 | /* no rang specified */
+                 ;
+ IfsOptions      : /* no options */
+                 | IfsOptions tMINSIZE Expr
+                 {
+                         ifsOptions.size = $3;
+                 }
+                 | IfsOptions tMAXDEPTH IExpr
+                 {
+                         ifsOptions.depth = $3;
+                 }
+                 | IfsOptions tNORMALWEIGHTING IfsNormalWeightingMethod
+                 {
+                         ifsOptions.normalweighting = $3;
+ 		}
+ 		| IfsOptions tBOUNDING IfsBoundingVolumeType
+ 		{
+ 		}
+ 		| IfsOptions tLIST Filename
+ 		{
+ 			ifsOptions.listfilename = strsave($3);
+ 		}
+                 ;
+ IfsNormalWeightingMethod: tCONSTANT
+                 {
+                         $$ = CONSTANT_NORMAL_WEIGHTING;
+                 }
+                 | tLOWPASS
+                 {
+                         $$ = LOWPASS_NORMAL_WEIGHTING;
+                 }
+                 | tHIGHPASS
+                 {
+                         $$ = HIGHPASS_NORMAL_WEIGHTING;
+                 }
+                 ;
+ IfsBoundingVolumeType:	tBOX
+ 		{
+ 			ifsOptions.boxbounding = TRUE;
+ 			ifsOptions.spherebounding = FALSE;
+ 		}
+ 		| tSPHERE
+ 		{
+ 			ifsOptions.boxbounding = FALSE;
+ 			ifsOptions.spherebounding = TRUE;
  		}
  		;
  Outfile		: tOUTFILE Filename
